package rs.etf.es.algorithm.states;

import rs.etf.es.algorithm.Algorithm;
import rs.etf.es.algorithm.AlgorithmState;
import rs.etf.es.algorithm.Constants;
import rs.etf.es.algorithm.Instantiation;
import rs.etf.es.algorithm.JTextAreaLogger;
import rs.etf.es.algorithm.Node;
import rs.etf.es.algorithm.NodeAddressBook;
import rs.etf.es.algorithm.RequestManager;

public class SetPiAndLambdaValuesToZeroState implements AlgorithmState {

    private Algorithm algorithm;
    private Instantiation inst;

    @Override
    public void performAction() {
	JTextAreaLogger.instance().log("");

	Node instantiatedNode = NodeAddressBook.instance().getNode(inst.getVariableName());
	for (String value : instantiatedNode.getValues()) {
	    if (!value.equals(inst.getVariableValue())) {
		instantiatedNode.getLambdaValues().put(value, Constants.IMPOSSIBLE);
		JTextAreaLogger.instance().log("Setting lambda value in " + instantiatedNode.getName() + " for " + value + " to " + Constants.IMPOSSIBLE);
		instantiatedNode.getPiValues().put(value, Constants.IMPOSSIBLE);
		JTextAreaLogger.instance().log("Setting pi value in " + instantiatedNode.getName() + " for " + value + " to " + Constants.IMPOSSIBLE);
		instantiatedNode.setProbability(value, Constants.IMPOSSIBLE);
		JTextAreaLogger.instance().log("Setting probability in " + instantiatedNode.getName() + " for " + value + " to " + Constants.IMPOSSIBLE);
	    }
	}

	if (instantiatedNode.getParents().size() > 0) {
	    Node parent = instantiatedNode.getParents().get(0);
	    if (!inst.getVariableName().equals(NodeAddressBook.instance().getRoot().getName()) && !RequestManager.instance().isNodeInRequest(parent)) {
		// parent.sendLambdaMessageToThisNode(instantiatedNode);
		SendLambdaMessageState newState = new SendLambdaMessageState();
		newState.setAlgorithm(algorithm);
		newState.setReceiver(parent);
		newState.setSender(instantiatedNode);
		algorithm.pushAlgorithmState(newState);
	    }
	}

	for (Node child : instantiatedNode.getChildren()) {
	    if (!RequestManager.instance().isNodeInRequest(child)) {
		// child.sendPiMessageToThisNode(instantiatedNode);
		SendPiMessageState newState = new SendPiMessageState();
		newState.setAlgorithm(algorithm);
		newState.setSender(instantiatedNode);
		newState.setReceiver(child);
		algorithm.pushAlgorithmState(newState);
	    }
	}
    }

    @Override
    public void setAlgorithm(Algorithm algorithmClass) {
	algorithm = algorithmClass;
    }

    public Instantiation getInst() {
	return inst;
    }

    public void setInst(Instantiation inst) {
	this.inst = inst;
    }

    public AlgorithmState clone() {
	SetPiAndLambdaValuesToZeroState newState = new SetPiAndLambdaValuesToZeroState();
	newState.setAlgorithm(algorithm);
	newState.setInst(new Instantiation(inst.getVariableName(), inst.getVariableValue()));
	return newState;
    }

    @Override
    public void refreshNodes() {

    }

}
